// Package hash provides a thread-safe generic hash set implementation.
package hash

import (
	"sync"
)

// GlobalHashSet 全局哈希集合实例
var (
	globalHashSet *HashSet[string]
	once          sync.Once
)

// GlobalHashSet 获取全局哈希集合单例实例
func GlobalHashSet() *HashSet[string] {
	once.Do(func() {
		globalHashSet = NewHashSet[string]()
	})
	return globalHashSet
}

// Add 向全局哈希集合中添加元素
func Add(item string) {
	GlobalHashSet().Add(item)
}

// AddAll 向全局哈希集合中添加多个元素
func AddAll(items ...string) {
	GlobalHashSet().AddAll(items...)
}

// Contains 检查元素是否存在于全局哈希集合中
func Contains(item string) bool {
	return GlobalHashSet().Contains(item)
}

// Remove 从全局哈希集合中移除元素
func Remove(item string) bool {
	return GlobalHashSet().Remove(item)
}

// Size 获取全局哈希集合的大小
func Size() int {
	return GlobalHashSet().Size()
}

// IsEmpty 检查全局哈希集合是否为空
func IsEmpty() bool {
	return GlobalHashSet().IsEmpty()
}

// Clear 清空全局哈希集合
func Clear() {
	GlobalHashSet().Clear()
}

// Items 获取全局哈希集合中的所有元素
func Items() []string {
	return GlobalHashSet().Items()
}

// HasAny 检查是否有任何给定元素存在于全局集合中
func HasAny(items ...string) bool {
	return GlobalHashSet().HasAny(items...)
}

// HasAll 检查是否所有给定元素都存在于全局集合中
func HasAll(items ...string) bool {
	return GlobalHashSet().HasAll(items...)
}

// HashSet 哈希集合结构体，用于100%准确的过滤
// 使用泛型支持任意可比较类型
type HashSet[T comparable] struct {
	items map[T]struct{}
	mu    sync.RWMutex
}

// NewHashSet 创建一个新的哈希集合
// 使用示例:
//
//	set := NewHashSet[string]()
//	set.Add("item")
func NewHashSet[T comparable]() *HashSet[T] {
	return &HashSet[T]{
		items: make(map[T]struct{}),
	}
}

// NewHashSetWithCapacity 创建一个指定初始容量的哈希集合

func NewHashSetWithCapacity[T comparable](capacity int) *HashSet[T] {
	return &HashSet[T]{
		items: make(map[T]struct{}, capacity),
	}
}

// Add 向哈希集合中添加元素

func (h *HashSet[T]) Add(item T) {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.items[item] = struct{}{}
}

// AddAll 向哈希集合中添加多个元素

func (h *HashSet[T]) AddAll(items ...T) {
	if len(items) == 0 {
		return
	}
	
	h.mu.Lock()
	defer h.mu.Unlock()
	
	// 批量添加元素
	for _, item := range items {
		h.items[item] = struct{}{}
	}
}

// Contains 检查元素是否存在于哈希集合中 (100%准确)

func (h *HashSet[T]) Contains(item T) bool {
	h.mu.RLock()
	defer h.mu.RUnlock()
	_, exists := h.items[item]
	return exists
}

// Remove 从哈希集合中移除元素

func (h *HashSet[T]) Remove(item T) bool {
	h.mu.Lock()
	defer h.mu.Unlock()
	_, exists := h.items[item]
	if exists {
		delete(h.items, item)
	}
	return exists
}

// Size 返回哈希集合的大小

func (h *HashSet[T]) Size() int {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return len(h.items)
}

// IsEmpty 检查哈希集合是否为空

func (h *HashSet[T]) IsEmpty() bool {
	return h.Size() == 0
}

// Clear 清空哈希集合

func (h *HashSet[T]) Clear() {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.items = make(map[T]struct{})
}

// Items 返回哈希集合中的所有元素

func (h *HashSet[T]) Items() []T {
	h.mu.RLock()
	defer h.mu.RUnlock()
	keys := make([]T, 0, len(h.items))
	for k := range h.items {
		keys = append(keys, k)
	}
	return keys
}

// HasAny 检查是否有任何给定元素存在于集合中

func (h *HashSet[T]) HasAny(items ...T) bool {
	h.mu.RLock()
	defer h.mu.RUnlock()
	for _, item := range items {
		if _, exists := h.items[item]; exists {
			return true
		}
	}
	return false
}

// HasAll 检查是否所有给定元素都存在于集合中

func (h *HashSet[T]) HasAll(items ...T) bool {
	h.mu.RLock()
	defer h.mu.RUnlock()
	for _, item := range items {
		if _, exists := h.items[item]; !exists {
			return false
		}
	}
	return true
}

// Clone 创建哈希集合的一个副本
// 时间复杂度: O(n)，n为原集合大小
// 使用示例:
//
//	clonedSet := set.Clone()
func (h *HashSet[T]) Clone() *HashSet[T] {
	h.mu.RLock()
	defer h.mu.RUnlock()
	newSet := NewHashSetWithCapacity[T](len(h.items))
	for k := range h.items {
		newSet.items[k] = struct{}{}
	}
	return newSet
}

// Union 返回两个集合的并集
// 时间复杂度: O(m+n)，m和n分别为两个集合的大小
// 使用示例:
//
//	unionSet := set1.Union(set2)
func (h *HashSet[T]) Union(other *HashSet[T]) *HashSet[T] {
	h.mu.RLock()
	defer h.mu.RUnlock()

	other.mu.RLock()
	defer other.mu.RUnlock()

	// 创建一个至少能容纳两个集合元素的新集合
	unionSet := NewHashSetWithCapacity[T](len(h.items) + len(other.items))

	// 添加第一个集合的所有元素
	for k := range h.items {
		unionSet.items[k] = struct{}{}
	}

	// 添加第二个集合的所有元素
	for k := range other.items {
		unionSet.items[k] = struct{}{}
	}

	return unionSet
}

// Intersection 返回两个集合的交集
// 时间复杂度: O(min(m,n))，m和n分别为两个集合的大小
// 使用示例:
//
//	intersectionSet := set1.Intersection(set2)
func (h *HashSet[T]) Intersection(other *HashSet[T]) *HashSet[T] {
	h.mu.RLock()
	defer h.mu.RUnlock()

	other.mu.RLock()
	defer other.mu.RUnlock()

	// 创建一个新集合
	intersectionSet := NewHashSet[T]()

	// 为了提高效率，遍历较小的集合
	smaller, larger := h.items, other.items
	if len(other.items) < len(h.items) {
		smaller, larger = other.items, h.items
	}

	// 检查较小集合中的每个元素是否也在较大集合中
	for k := range smaller {
		if _, exists := larger[k]; exists {
			intersectionSet.items[k] = struct{}{}
		}
	}

	return intersectionSet
}